package com.meshnetics.gb.type;

import java.nio.ByteBuffer;

/**
 * Type of data element.
 *
 * @author AKovylin
 */
public interface DataType {
    /**
     * Returns name of the type. Name returned by this method is considered as "main" name, all other names
     * under which this type can be recognized are called aliases (moreover, "main" name is considered as
     * one of aliases but some kind of special alias).
     *
     * @return name of the type
     */
    String getName();

    /**
     * Returns all supported aliases for type name (for example, "int" is aliase for "integer").
     * <br><br>
     * "Main" name of type must be returned as first element of array.
     *
     * @return all supported aliases for type name
     */
    String[] getAliases();

    /**
     * Returns data type id in accordance with ZCL.
     *
     * @return data type id
     */
    DataTypeID getDataTypeID();

    /**
     * Converts byte array to value. All bytes of byte array are considered to be a value. If only part of byte array
     * must be converted to value {@link #deserialize(java.nio.ByteBuffer)} should be used. Byte order in array
     * of bytes should be Big Endian.
     *
     * @param value byte array representation of value
     * @return value of this type, that was converted to byte array
     * @throws IllegalArgumentException thrown if content of byte array is not a value of this type
     * @throws NullPointerException     thrown if value is null
     */
    DataValue valueOf(byte[] value);

    /**
     * Converts string to value. All characters of string are considered to be a value. If only part of string
     * must be converted to value special mark up should be used when value is written to string, so only
     * substring can be passed here.
     *
     * @param value string representation of value
     * @return value of this type, that was converted to string
     * @throws IllegalArgumentException thrown if content of string is not a value of this type
     * @throws NullPointerException     thrown if value is null
     */
    DataValue valueOf(String value);

    /**
     * Creates value from Java object corresponding to this data type.
     *
     * @param value Java object corresponding to data type
     * @return value of this type, that was created from object
     * @throws IllegalArgumentException thrown if Java object doesn't represent this data type
     * @throws NullPointerException     thrown if value is null
     */
    DataValue fromObject(Object value);

    /**
     * Reads value from current position in <code>ByteBuffer</code>.
     *
     * @param bb ByteBuffer with value serialized in it, position should point the start of value
     * @return value of this type, that was serialized in buffer
     * @throws IllegalArgumentException thrown if there's not enough bytes left in ByteBuffer for conversion or
     *                                  content of ByteBuffer starting from current position can't be converted
     *                                  to value of this type
     * @throws NullPointerException     thrown if bb is null
     */
    DataValue deserialize(ByteBuffer bb);

    /**
     * Returns mandatory for this type. The string serialized form of value must be same as produced by this formatter.
     *
     * @return mandatory formatter
     */
    MandatoryFormatter getMandatoryFormatter();
}
